home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
network
/
ka9q
/
ka9q_src.arc
/
AX25CMD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-07-28
|
12KB
|
596 lines
#include <stdio.h>
#include "global.h"
#include "mbuf.h"
#include "ax25.h"
#include "timer.h"
#include "iface.h"
#include "lapb.h"
#include "cmdparse.h"
#include "session.h"
#include "st.h" /* DG2KK */
extern struct tcb;
#define NULLTCB (struct tcb *)0
#ifdef FLOW
extern int ttyflow; /* DG2KK (output flowcontrol) */
#endif
char *ax25states[] = {
"Disconnected",
"Conn pending",
"Disc pending",
"Connected",
"Frame Reject",
};
int domycall(),dodigipeat(),doaxstat(),dot1(),dot2(),dot3(),domaxframe(),
doaxwindow(),dopaclen(),don2(),doaxreset(),doconok(); /* DG2KK */
static struct cmds axcmds[] = {
"conok", doconok, 0, NULLCHAR, NULLCHAR, /* DG2KK */
"digipeat", dodigipeat, 0, NULLCHAR, NULLCHAR,
"maxframe", domaxframe, 0, NULLCHAR, NULLCHAR,
"mycall", domycall, 0, NULLCHAR, NULLCHAR,
"paclen", dopaclen, 0, NULLCHAR, NULLCHAR,
"reset", doaxreset, 2, "ax25 reset <axcb>", NULLCHAR,
"retry", don2, 0, NULLCHAR, NULLCHAR,
"status", doaxstat, 0, NULLCHAR, NULLCHAR,
"t1", dot1, 0, NULLCHAR, NULLCHAR,
"t2", dot2, 0, NULLCHAR, NULLCHAR,
"t3", dot3, 0, NULLCHAR, NULLCHAR,
"window", doaxwindow, 0, NULLCHAR, NULLCHAR,
NULLCHAR, NULLFP, 0, "ax25 subcommands: digipeat maxframe mycall paclen reset retry status\n\tt1 t2 t3 window", NULLCHAR,
};
/* Multiplexer for top-level ax25 command */
doax25(argc,argv)
int argc;
char *argv[];
{
return subcmd(axcmds,argc,argv);
}
static
doaxreset(argc,argv)
int argc;
char *argv[];
{
struct ax25_cb *axp;
extern char notval[];
long htol();
axp = (struct ax25_cb *)htol(argv[1]);
if(!ax25val(axp)){
printf(notval);
return 1;
}
reset_ax25(axp);
return 0;
}
/* Display AX.25 link level control blocks */
static
doaxstat(argc,argv)
int argc;
char *argv[];
{
register int i;
register struct ax25_cb *axp;
char tmp[10];
extern char notval[];
long htol();
if(argc < 2){
printf(" &AXB IF Snd-Q Rcv-Q Remote State\n");
for(i=0;i<NHASH;i++){
for(axp = ax25_cb[i];axp != NULLAX25; axp = axp->next){
pax25(tmp,&axp->addr.dest);
printf("%8lx %-5s%-8d%-8d%-10s%s\n",
(long)axp,axp->interface->name,
len_q(axp->txq),len_mbuf(axp->rxq),
tmp,ax25states[axp->state]);
}
}
return 0;
}
axp = (struct ax25_cb *)htol(argv[1]);
if(!ax25val(axp)){
printf(notval);
return 1;
}
dumpstat(axp);
return 0;
}
/* Dump one control block */
static
dumpstat(axp)
register struct ax25_cb *axp;
{
char tmp[10];
int i;
if(axp == NULLAX25 || axp->interface == NULLIF)
return;
/* DG2KK: changed "&AXB IF..." to " &AXB IF..." (Atari has 5 digit addr. */
printf(" &AXB IF Remote RBW V(S) V(R) Unack P Retry T1 T2 T3 State\n");
pax25(tmp,&axp->addr.dest);
printf("%4x %-5s%-9s",(int)axp,axp->interface->name,tmp);
putchar(axp->rejsent ? 'R' : ' ');
putchar(axp->remotebusy ? 'B' : ' ');
putchar(axp->waitack ? 'W' : ' ');
printf(" %4d %4d",axp->vs,axp->vr);
printf(" %02d/%02d %d",axp->unack,axp->maxframe,axp->proto);
printf(" %02d/%02d",axp->retries,axp->n2);
if(run_timer(&axp->t1))
printf(" %02d/%02d",axp->t1.start - axp->t1.count,
axp->t1.start);
else
printf(" /%02d",axp->t1.start);
if(run_timer(&axp->t2))
printf(" %02d/%02d",axp->t2.start - axp->t2.count,
axp->t2.start);
else
printf(" /%02d",axp->t2.start);
if(run_timer(&axp->t3))
printf(" %02d/%02d",axp->t3.start - axp->t3.count,
axp->t3.start);
else
printf(" /%02d",axp->t3.start);
printf(" %s\n",ax25states[axp->state]);
if(axp->addr.ndigis == 0)
return;
printf("Digipeaters:");
for(i=0;i<axp->addr.ndigis;i++){
pax25(tmp,&axp->addr.digis[i]);
printf(" %s",tmp);
}
printf("\n");
}
/* Display or change our AX.25 address */
static
domycall(argc,argv)
int argc;
char *argv[];
{
char buf[15];
if(argc < 2){
pax25(buf,&mycall);
printf("%s\n",buf);
return 0;
}
if(setcall(&mycall,argv[1]) == -1)
return -1;
mycall.ssid |= E;
return 0;
}
/* Control AX.25 digipeating */
static
dodigipeat(argc,argv)
int argc;
char *argv[];
{
extern int digipeat;
if(argc == 1) {
printf("digipeat %s\n",digipeat ? "on" : "off");
} else {
if(strcmp(argv[1],"on") == 0)
digipeat = 1;
else
digipeat = 0;
}
}
/* Set retransmission timer */
static
dot1(argc,argv)
int argc;
char *argv[];
{
extern int16 t1init;
if(argc == 1) {
printf("T1 %d\n",t1init);
} else {
t1init = atoi(argv[1]);
}
}
/* Set acknowledgement delay timer */
static
dot2(argc,argv)
int argc;
char *argv[];
{
extern int16 t2init;
if(argc == 1) {
printf("T2 %d\n",t2init);
} else {
t2init = atoi(argv[1]);
}
}
/* Set idle timer */
static
dot3(argc,argv)
int argc;
char *argv[];
{
extern int16 t3init;
if(argc == 1) {
printf("T3 %d\n",t3init);
} else {
t3init = atoi(argv[1]);
}
}
/* Set retry limit count */
static
don2(argc,argv)
int argc;
char *argv[];
{
extern int16 n2;
if(argc == 1) {
printf("Retry %d\n",n2);
} else {
n2 = atoi(argv[1]);
}
}
/* Set maximum number of frames that will be allowed in flight */
static
domaxframe(argc,argv)
int argc;
char *argv[];
{
extern int16 maxframe;
if(argc == 1) {
printf("Maxframe %d\n",maxframe);
} else {
maxframe = atoi(argv[1]);
}
}
/* Set maximum length of I-frame data field */
static
dopaclen(argc,argv)
int argc;
char *argv[];
{
extern int16 paclen;
if(argc == 1) {
printf("Paclen %d\n",paclen);
} else {
paclen = atoi(argv[1]);
}
}
/* Set high water mark on receive queue that triggers RNR */
static
doaxwindow(argc,argv)
int argc;
char *argv[];
{
extern int16 axwindow;
if(argc == 1) {
printf("Axwindow %d\n",axwindow);
} else {
axwindow = atoi(argv[1]);
}
}
/* End of ax25 subcommands */
/* Initiate interactive AX.25 connect to remote station */
doconnect(argc,argv)
int argc;
char *argv[];
{
void ax_rx(),ax_tx(),ax_state();
int ax_parse();
struct ax25_addr dest;
struct ax25 addr;
struct ax25_cb *open_ax25();
struct interface *ifp;
struct session *s;
extern int16 axwindow;
int i;
for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
if(strcmp(argv[1],ifp->name) == 0)
break;
if(ifp == NULLIF){
printf("Interface %s unknown\n",argv[1]);
return 1;
}
setcall(&dest,argv[2]);
/* See if a session already exists */
for(s = sessions; s < &sessions[nsessions]; s++){
if(s->type == AX25TNC
&& addreq(&s->cb.ax25_cb->addr.dest,&dest)){
#if ( MAC || AMIGA )
printf("Session %lu to %s already exists\n",
#else
printf("Session %u to %s already exists\n",
#endif
s - sessions,argv[2]);
return 1;
}
}
/* Allocate a session descriptor */
if((s = newsession()) == NULLSESSION){
printf("Too many sessions\n");
return 1;
}
if((s->name = malloc((unsigned)strlen(argv[2])+1)) != NULLCHAR)
strcpy(s->name,argv[2]);
s->type = AX25TNC;
s->parse = ax_parse;
current = s;
ASSIGN(addr.source,mycall); /* DG2KK: should be changed */
setcall(&addr.dest,argv[2]);
for(i=3; i < argc; i++)
setcall(&addr.digis[i-3],argv[i]);
addr.ndigis = i - 3;
s->cb.ax25_cb = open_ax25(&addr,axwindow,ax_rx,ax_tx,ax_state,ifp,(char *)s);
go();
return 0;
}
/* Display changes in AX.25 state */
void
ax_state(axp,old,new)
struct ax25_cb *axp;
int old,new;
{
struct session *s;
char remote[10]; /* DG2KK */
s = (struct session *)axp->user;
if(current != NULLSESSION && current->type == AX25TNC && current == s){
printf("%s\n",ax25states[new]);
/* added to enable a 'bell' when state is connected */
/* ---- DG2KK: AX25 logging ---- */
if(new == CONNECTED) {
printf("\007");
pax25(remote,&axp->addr.dest);
log(NULLTCB,"Connected to %s",remote);
}
if(new == DISCONNECTED) {
pax25(remote,&axp->addr.dest);
log(NULLTCB,"Disconnected from %s",remote);
cmdmode();
}
/* ----- */
fflush(stdout);
}
if(new == DISCONNECTED){
axp->user = NULLCHAR;
freesession(s);
}
}
/* Handle typed characters on AX.25 connection */
int
ax_parse(buf,cnt)
char *buf;
int16 cnt;
{
struct mbuf *bp;
register char *cp;
char c;
if(current == NULLSESSION || current->type != AX25TNC)
return; /* "can't happen" */
/* If recording is on, record outgoing stuff too */
if(current->record != NULLFILE)
fwrite(buf,1,cnt,current->record);
/* Allocate buffer and start it with the PID */
b